package org.kernely.stream;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.kernely.core.service.KernelyBundleService;
import org.kernely.mail.service.KernelyMailService;
import org.kernely.security.service.KernelySecurityService;
import org.kernely.stream.administration.StreamAdministrationPresenter;
import org.kernely.stream.administration.StreamAdministrationView;
import org.kernely.stream.messageFilter.ImageFilter;
import org.kernely.stream.messageFilter.LinkFilter;
import org.kernely.stream.messageFilter.MailFilter;
import org.kernely.stream.service.KernelyStreamService;
import org.kernely.stream.userpage.StreamUserPagePresenter;
import org.kernely.stream.userpage.StreamUserPageView;
import org.kernely.ui.mvp.IKernelyView;
import org.kernely.ui.mvp.KernelyEventBus;
import org.kernely.ui.mvp.KernelyViewPresenterManager;
import org.kernely.ui.mvp.ViewIdentifier;
import org.kernely.ui.services.KernelyUIBundle;
import org.kernely.ui.services.KernelyUIBundleService;
import org.kernely.ui.utils.KernelyBundleMenu;

import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.Resource;

/**
 * The stream bundle manages streams and messages (like a social network).
 */
public class StreamBundle implements KernelyUIBundle {
	
	/**
	 * The UI registering service
	 */
	private static KernelyUIBundleService uiBundleService;

	/**
	 * The security service : retrieving current user, roles...
	 */
	private static KernelySecurityService securityService;
	
	/**
	 * The streams service : create stream...
	 */
	private static KernelyStreamService streamService;
	
	private static KernelyMailService mailService;
	
	/**
	 * Set the mail service (by OSGi Declarative services), declared by the mail bundle.
	 */
	public final void setMailService(KernelyMailService mailService) {
		StreamBundle.mailService = mailService;
		
		// Register the mail filter
		StreamBundle.getStreamService().registerStreamFilter(new MailFilter());
	}
	
	/**
	 * Unset the mail service (by OSGi Declarative services), declared by the mail bundle.
	 */
	public final void unsetMailService(KernelyMailService mailService) {
		StreamBundle.mailService = null;
	}
	
	/**
	 * Get the mail service to use it.
	 */
	public static final KernelyMailService getMailService() {
		return StreamBundle.mailService;
	}
	
	/**
	 * Gets the security service.
	 * @return the security service.
	 */
	public static KernelySecurityService getSecurityService() {
		return securityService;
	}

	/**
	 * Get the event bus to send events.
	 */
	public static KernelyEventBus getEventBus() {
		Session session = (Session) SecurityUtils.getSubject().getSession();
		return (KernelyEventBus) session.getAttribute("eventBus");
		
	}
	
	/**
	 * Method called by the Service Component Runtime
	 * 
	 * @param service
	 *            : the KernelyBundleService needed to register this bundle
	 */
	public final void setModuleService(KernelyBundleService service) {
		// Registering the bundle
		service.registerModule(this);
	}

	/**
	 * Method called by the Service Component Runtime
	 * 
	 * @param service
	 *            : the KernelyBundleService needed to unregister this bundle
	 */
	public final void unsetModuleService(KernelyBundleService service) {
		// Unregistering the bundle
		service.unregisterModule(this);
	}

	/**
	 * Sets the KernelyUIBundleService Declarative Service.
	 * 
	 * @param uiBundleService
	 *            : the KernelyUIBundleService service
	 */
	public final void setUIBundleService(KernelyUIBundleService uiBundleService) {
		StreamBundle.uiBundleService = uiBundleService;
		StreamBundle.uiBundleService.registerModule(this);
	}

	/**
	 * Unsets the KernelyUIBundleService Declarative Service.
	 * 
	 * @param uiBundleService
	 *            : the KernelyUIBundleService service
	 */
	public final void unsetUIBundleService(KernelyUIBundleService service) {
		StreamBundle.uiBundleService.unregisterModule(this);
	}
	
	/**
	 * Sets the security Declarative Service
	 * @param service The security service.
	 */
	public final void setSecurityService(KernelySecurityService service) {
		securityService = service;
	}

	/**
	 * Unsets the security Declarative Service
	 * @param service The security service.
	 */
	public final void unsetSecurityService(KernelySecurityService service) {}

	/**
	 * Get the administration view of the stream bundle.
	 */
	public final Class<? extends IKernelyView> getAdministrationView() {
		return StreamAdministrationView.ID_VIEW;
	}

	/**
	 * @see org.kernely.ui.services.KernelyUIBundle#getMenu()
	 */
	public final KernelyBundleMenu getMenu() {
		KernelyBundleMenu menu = new KernelyBundleMenu();
		menu.put("Streams", StreamUserPageView.ID_VIEW);
		
		menu.setMenuIcon("Streams", "streambundle/images/stream_16*16.png");
		return menu;
	}


	/**
	 * @see org.kernely.ui.services.KernelyUIBundle#getViewPresenter()
	 */
	public final KernelyViewPresenterManager getViewPresenter() {
		KernelyViewPresenterManager hm = new KernelyViewPresenterManager();
		// Adding all associations View - Presenter
		hm.put(StreamAdministrationView.class, StreamAdministrationPresenter.class);
		hm.put(StreamUserPageView.class, StreamUserPagePresenter.class);
		return hm;
	}

	/**
	 * Return the name of the stream bundle.
	 * @return the name of the bundle.
	 */
	public final String getName() {
		return "Stream Bundle";
	}
	
	/**
	 * @see org.kernely.ui.mvp.KernelyUIBundle#getIcon()
	 */
	public final Resource getIcon() {
		return new ExternalResource("streambundle/images/stream_32*32.png");
	}

	/**
	 * Set the stream service, managed by Declarative Service.
	 * @param service the stream service.
	 */
	public final void setStreamService(KernelyStreamService service) {
		streamService = service;
		
		// We register all filters provided by this bundle.
		StreamBundle.getStreamService().registerStreamFilter(new LinkFilter());
		StreamBundle.getStreamService().registerStreamFilter(new ImageFilter());
	}

	/**
	 * Unset the stream service, managed by Declarative Service.
	 * @param the service.
	 */
	public final void unsetStreamService(KernelyStreamService service) {}

	/**
	 * Get the stream service, managed by Declarative Service.
	 * @param service the stream service.
	 */
	public static KernelyStreamService getStreamService(){
		return streamService;
	}

	/**
	 * @see org.kernely.ui.services.KernelyUIBundle#getFrontPages()
	 */
	public Set<ViewIdentifier> getFrontPages() {
		// Create the set
		HashSet<ViewIdentifier> views = new HashSet<ViewIdentifier>();
		// Add the view
		views.add(new ViewIdentifier("Streams page", (StreamUserPageView.class).toString(),this.getName()));
		return views;
	}

}
